using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using Sixeyed.CacheAdapter.PipelineComponents.Tests.Properties;
using Microsoft.BizTalk.Message.Interop;
using Winterdom.BizTalk.PipelineTesting;
using Microsoft.BizTalk.Component;
using System.Xml;
using Sixeyed.CacheAdapter.Management;
using Sixeyed.CacheAdapter.Configuration;
using Sixeyed.CacheAdapter.Interfaces;

namespace Sixeyed.CacheAdapter.PipelineComponents.Tests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class CheckIsCachedTest
    {
        private TransmitLocation _transmitLocation = TransmitLocation.Deserialize(Resources.TransmitLocation);
        private ReceivePipelineWrapper _receivePipeline;

        private ReceivePipelineWrapper ReceivePipeline
        {
            get
            {
                if (this._receivePipeline == null)
                {
                    this._receivePipeline = PipelineFactory.CreateEmptyReceivePipeline();
                    XmlDasmComp xmlDasm = new XmlDasmComp();
                    xmlDasm.AllowUnrecognizedMessage = true;
                    this._receivePipeline.AddComponent(xmlDasm, PipelineStage.Disassemble);
                    SetMessageCacheProperties messageCache = new SetMessageCacheProperties();
                    messageCache.IsCacheEnabled = true;
                    messageCache.IsMessageTypeConfigurationEnabled = true;
                    this._receivePipeline.AddComponent(messageCache, PipelineStage.Validate);
                    CheckIsCached check = new CheckIsCached();
                    check.CacheProviderTypeName = this._transmitLocation.Provider;
                    check.CacheProviderConfiguration = this._transmitLocation.Configuration;
                    this._receivePipeline.AddComponent(check, PipelineStage.Validate);
                }
                return this._receivePipeline;
            }
        }

        public CheckIsCachedTest() { }

        [TestMethod]
        public void Execute_ConfiguredMessage()
        {
            IBaseMessage inputMessage = MessageHelper.CreateFromString(Resources.GetXYZMessage);
            MessageCollection outputMessages = this.ReceivePipeline.Execute(inputMessage);
            Assert.AreEqual(1, outputMessages.Count);
            //XYZ message should be configured for caching:
            IBaseMessage outputMessage = outputMessages[0];
            object value = outputMessage.Context.Read(MessageCacheProperties.PropertyName.IsMessageCacheEnabled, MessageCacheProperties.Namespace.CacheAdapter);
            Assert.IsNotNull(value);
            Assert.AreEqual(true, (bool)value);
            //and the cache key should be set:
            value = outputMessage.Context.Read(MessageCacheProperties.PropertyName.MessageCacheKey, MessageCacheProperties.Namespace.CacheAdapter);
            Assert.IsNotNull(value);
            Assert.IsTrue(((string)value).Length > 0);
            //but the object is not in cache:
            value = outputMessage.Context.Read(MessageCacheProperties.PropertyName.IsCached, MessageCacheProperties.Namespace.CacheAdapter);
            Assert.IsNotNull(value);
            Assert.IsFalse((bool)value);
        }

        [TestMethod]
        public void Execute_CachedMessage()
        {
            ICacheProviderConfiguration config = this._transmitLocation.GetCacheConfiguration();
            ICacheProvider provider = CacheFactory.GetProvider(this._transmitLocation.Provider, config);
            
            //cache an object:
            string cacheKey = provider.GetCacheKey();
            provider.Put(cacheKey, new byte[0]);
            //set up the message with a cache key:
            IBaseMessage inputMessage = MessageHelper.CreateFromString(Resources.GetXYZMessage);            
            inputMessage.Context.Write(MessageCacheProperties.PropertyName.MessageCacheKey, MessageCacheProperties.Namespace.CacheAdapter, cacheKey);
            //execute:
            MessageCollection outputMessages = this.ReceivePipeline.Execute(inputMessage);
            Assert.AreEqual(1, outputMessages.Count);
            //XYZ message should be configured for caching:
            IBaseMessage outputMessage = outputMessages[0];
            object value = outputMessage.Context.Read(MessageCacheProperties.PropertyName.IsMessageCacheEnabled, MessageCacheProperties.Namespace.CacheAdapter);
            Assert.IsNotNull(value);
            Assert.AreEqual(true, (bool)value);
            //and the cache key should be set:
            value = outputMessage.Context.Read(MessageCacheProperties.PropertyName.MessageCacheKey, MessageCacheProperties.Namespace.CacheAdapter);
            Assert.IsNotNull(value);
            Assert.AreEqual(cacheKey, (string) value);
            //and the object is not in cache:
            value = outputMessage.Context.Read(MessageCacheProperties.PropertyName.IsCached, MessageCacheProperties.Namespace.CacheAdapter);
            Assert.IsNotNull(value);
            Assert.IsTrue((bool)value);
        }
    }
}
